﻿using System;
using System.Linq;
using JinfuyuanProject.Entity;
using JinfuyuanProject.Service.Interface;
using JinfuyuanProject.Repository.Interface;
using System.Collections;
using JinfuyuanProject.Entity.ViewModels;
using System.Data.Entity;
using System.IO;
using System.Configuration;
using ZXing;
using ZXing.Common;
using System.Web;

using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using DocumentFormat.OpenXml.EMMA;
using Microsoft.AspNet.SignalR;
using DocumentFormat.OpenXml.EMMA;
using DotNet.Utilities;
using JinfuyuanProject.Repository;



namespace JinfuyuanProject.Service
{
    public class ProductService : IProductService
    {
        private readonly IProductRepository _productRepository;
        private readonly JinfuyuanDbContext _db;
        private readonly IProductApplicationRepository _productApplicationRepository;
        private readonly IContractRepository _contractRepository;
        private readonly IExpenseRecordRepository _expenseRecordRepository;

        public ProductService(IProductRepository productRepository, JinfuyuanDbContext db,IProductApplicationRepository productApplicationRepository,IContractRepository contractRepository,IExpenseRecordRepository expenseRecordRepository)
        {
            _productRepository = productRepository;
            _db = db;
            _productApplicationRepository= productApplicationRepository;
            _contractRepository= contractRepository;
            _expenseRecordRepository = expenseRecordRepository;
        }
        #region 基础方法
        public bool Delete(Product product)
        {
            return _productRepository.Delete(product);
        }

        public IQueryable<Product> GetList()
        {
            return _productRepository.GetList();
        }

        public Product GetModel(int Id)
        {
            return _productRepository.GetModel(Id);
        }

        public int Insert(Product product)
        {
            return _productRepository.Insert(product);
        }

        public bool Update(Product product)
        {
            return _productRepository.Update(product);
        }
        #endregion
        #region 业务方法
        public Hashtable Query(ProductFilter filter)
        {
            int count;
            List<Product> productList = GetList().ToList();//两表关联 使用linq  多表复杂SQL 使用QueryBySql
            //List<Product> productList = GetData();//两表关联 使用linq  多表复杂SQL 使用QueryBySql
            Hashtable hashtable = new Hashtable();
            hashtable["code"] = 0;
            hashtable["message"] = "success";
            hashtable["data"] = MakeQueryFilter(productList, filter, out count);
            hashtable["count"] = count;//结束惰性加载
            return hashtable;
        }
        public List<Product> GetData()
        {
            using (var sqlconnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Jinfuyuan2025"].ConnectionString))
            {
                sqlconnection.Open();
                using (SqlCommand cmd = new SqlCommand("SELECT Id,ProductName,ProductFactory,Price,ImgUrl,Number,Barcode,Threshold,CreateTime,IsDelete FROM dbo.Product", sqlconnection))
                {
                    cmd.Notification = null;
                    //SQL依赖对象
                    SqlDependency dependency = new SqlDependency(cmd);
                    //事件
                    dependency.OnChange += new OnChangeEventHandler(dependency_Onchange);
                    if (sqlconnection.State == ConnectionState.Closed)
                        sqlconnection.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    List<Product> list = new List<Product>();
                    while (reader.Read())
                    {
                        Product m = new Product();
                        m.Id = Convert.ToInt32(reader["Id"]);
                        m.ProductFactory = Convert.ToString(reader["ProductFactory"]);
                        m.ProductName = Convert.ToString(reader["ProductName"]);
                        m.Price = Convert.ToDecimal(reader["Price"]);
                        m.ImgUrl = Convert.ToString(reader["ImgUrl"]);
                        m.Number = Convert.ToInt32(reader["Number"]);
                        m.Barcode = Convert.ToString(reader["Barcode"]);
                        m.Threshold = Convert.ToInt32(reader["Threshold"]);
                        m.CreateTime = Convert.ToDateTime(reader["CreateTime"]);
                        m.IsDelete = Convert.ToInt32(reader["IsDelete"]);
                        list.Add(m);
                    }

                    return list;
                }
            }
        }
        public void dependency_Onchange(object sender, SqlNotificationEventArgs e)
        {
            if (e.Type == SqlNotificationType.Change)
            {
                IHubContext chat = GlobalHost.ConnectionManager.GetHubContext("myChatHub");
                chat.Clients.All.RevStudents(Newtonsoft.Json.JsonConvert.SerializeObject(GetData()));
            }

        }
        //出库人名字查询
        public Hashtable SearchName(string keywords)
        {
            Hashtable hashtable = new Hashtable();
            var list = GetList().Where(x => x.ProductName.Contains(keywords));
            hashtable["code"] = 0;
            hashtable["msg"] = "success";
            hashtable["data"] = list;
            hashtable["count"] = list.Count();
            return hashtable;
        }
        //商品表创建事务
        public Hashtable NewProductProcurement(ProductVM productVm,int Id)
        {
            var result = new Hashtable();
            // 输入验证
            if (productVm == null)
            {
                result["code"] = 1;
                result["message"] = "参数不能为空";
                return result;
            }
            // 开始事务
            var transaction = _db.Database.BeginTransaction();
            try
            {
                // 1. 创建新商品记录
                var newProduct = new Product
                {
                    ProductName = productVm.ProductName,      // 商品名称
                    Number = productVm.Number,
                    ProductFactory = productVm.ProductFactory,// 生产厂家
                    Price = decimal.Parse(productVm.Price),   // 销售价（字符串转decimal）
                    ImgUrl = null,
                    Threshold = productVm.Threshold,
                    CreateTime = DateTime.Now,
                    IsDelete = 0
                };
                //生成条形码 
                newProduct.Barcode = GenerateBarcode(productVm);
                _db.Product.Add(newProduct); // 添加到数据库
                _db.SaveChanges();           // 保存以获取自动生成的ID

                // 2. 创建入库记录
                var inbound = new Inbound
                {
                    ProductId = newProduct.Id,           // 关联商品ID
                    Number = productVm.Number,
                    InboundId = Id,
                    InboundTime = DateTime.Now,
                    CreateTime = DateTime.Now,
                    IsDelete = 0,
                    Type = 1
                };
                _db.Inbound.Add(inbound);
                // 3. 创建批次记录
                var procurement = new Procurements
                {
                    ProductId = newProduct.Id,           // 关联商品ID
                    PurcharName = productVm.PurcharName,
                    PurcharTime = DateTime.Now,
                    PurcharPrice = decimal.Parse(productVm.PurcharPrice),
                    Number = productVm.Number,
                    PurcharId = Id,
                    ProductionDate = DateTime.Now,
                    CreateTime = DateTime.Now,
                    IsDelete = 0
                };
                _db.Procurements.Add(procurement);
                // 保存所有剩余更改
                transaction.Commit();
                _db.SaveChanges();
                // 提交事务

            }
            catch (Exception ex)
            {
                transaction.Rollback();
            }
            result["code"] = 0;
            result["message"] = "success";
            return result;
        }
        //入库添加记录事务
        public Hashtable CreateInbound(ProductVM productVM, int uId)
        {
            var result = new Hashtable();

            // 1. 输入验证
            if (productVM == null)
            {
                result["code"] = 400;
                result["message"] = "请求参数无效";
                return result;
            }
            // 2. 开始事务
            var transaction = _db.Database.BeginTransaction();
            try
            {
                // 3. 获取现有商品
                var product = _db.Product
                    .Where(p => p.Id == productVM.Id && p.IsDelete == 0)
                    .FirstOrDefault();
                // 4. 创建入库记录
                var inbound = new Inbound
                {
                    ProductId = productVM.Id,           // 关联商品ID
                    Number = productVM.Number,
                    InboundId = uId,
                    InboundTime = DateTime.Now,
                    CreateTime = DateTime.Now,
                    IsDelete = 0,
                    Type = 1,
                    ApplicationId = uId
                };
                _db.Inbound.Add(inbound);


                // 5. 创建采购批次记录
                var procurement = new Procurements
                {
                    ProductId = productVM.Id,           // 关联商品ID
                    PurcharName = productVM.PurcharName,
                    PurcharTime = DateTime.Now,
                    PurcharPrice = decimal.Parse(productVM.PurcharPrice),
                    Number = productVM.Number,
                    PurcharId = uId,
                    ProductionDate = DateTime.Now,
                    CreateTime = DateTime.Now,
                    IsDelete = 0

                };
                _db.Procurements.Add(procurement);
                // 6. 更新商品库存
                product.Number += productVM.Number;
                _productRepository.Update(product);

                transaction.Commit();
                // 7. 统一提交
                _db.SaveChanges();


            }
            catch (Exception ex)
            {
                transaction.Rollback();
            }
            result["code"] = 0;
            result["message"] = "success";
            return result;
        }

        //出库添加事务
        public Hashtable CreateOutbound(List<InboundVM> productData)
        {
            var result = new Hashtable();
            List<MessageInfo> info = new List<MessageInfo>();
            // 2. 开始事务
            var transaction = _db.Database.BeginTransaction();
            try
            {
                foreach (var inboundVm in productData)
                {
                    if (inboundVm == null)
                    {
                        result["code"] = 400;
                        result["message"] = "请求参数无效";
                        return result;
                    }
                    var product = _db.Product
                       .Where(p => p.Id == inboundVm.ProductId && p.IsDelete == 0)
                       .FirstOrDefault();
                    if (product.Number < product.Threshold)
                    {
                        MessageInfo messageInfo = new MessageInfo()
                        {
                            Contents = $"请去进{product.Id}号商品",
                            StaffRecId = 1,
                            StaffSendId = 0,
                            CreateTime = DateTime.Now,
                            IsDelete = 0,
                            Href = "/Product/ProductList",
                            IsRead = 0,
                            Times = DateTime.Now
                        };
                        info.Add(messageInfo);
                    }
                    var inbound = new Inbound
                    {
                        ProductId = inboundVm.ProductId.Value,
                        Number = inboundVm.Number.Value,
                        InboundId = inboundVm.InboundId.Value,
                        InboundTime = DateTime.Now,
                        CreateTime = DateTime.Now,
                        IsDelete = 0,
                        Type = 0,
                        ApplicationId = inboundVm.InboundId.Value
                    };
                    _db.Inbound.Add(inbound);
                    if (info.Count > 0)
                    {
                        _db.MessageInfo.AddRange(info);
                    }
                    product.Number -= inboundVm.Number.Value;
                    _productRepository.Update(product);
                }
                transaction.Commit();
                _db.SaveChanges();


            }
            catch (Exception ex)
            {
                transaction.Rollback();
            }
            result["code"] = 0;
            result["message"] = "success";
            return result;
        }
        #endregion
        //过滤器
        public List<Product> MakeQueryFilter(List<Product> product, ProductFilter productFilter, out int count)
        {
            if (!string.IsNullOrEmpty(productFilter.ProductName))
            {
                product = product.Where(x => x.ProductName.Contains(productFilter.ProductName)).ToList();
            }
            if (productFilter.IsDelete != null)
            {
                product = product.Where(x => x.IsDelete == productFilter.IsDelete).ToList();
            }
            //需要过滤后没做分页前的所有数据条数
            count = product.Count();
            //做分页
            if (productFilter.page != 0 && productFilter.limit != 0)
                return product.OrderBy(x => x.Id).Skip((productFilter.page - 1) * productFilter.limit).Take(productFilter.limit).ToList();
            else
                return product;
        }
        //出入库审核
        public ResMessage ProductApi(int id, int uid)
        {

            Inbound inbound = _db.Inbound.Find(id);
            //inbound.InboundId = uid;
            int? ProductApplyId = inbound.ApplicationId;//物品申请表id
            string msg = "";
            //1.向消费清单表插入记录根据物品申请id
            ProductApplication productApply = _productApplicationRepository.GetModel((int)ProductApplyId);//根据物品申请id找到对应的物品申请信息
            productApply.VerifyId = uid;
            Product product = GetModel((int)productApply.ProductId);
            decimal? price = product.Price;//对应商品价格
            ExpenseRecord expenseRecord =new ExpenseRecord();
            expenseRecord.Cid = productApply.ContractId;
            expenseRecord.ConsId = productApply.ProductId;
            expenseRecord.Type = 1;
            expenseRecord.ConsCount = productApply.Number;
            expenseRecord.Price = price;
            expenseRecord.IsDelete = 0;
            expenseRecord.ApplyId = productApply.ApplicationId;//先写死
            expenseRecord.ReviewersId = uid;//先写死
            expenseRecord.CreateTime = DateTime.Now;
            Contract contract = _contractRepository.GetModel((int)productApply.ContractId);//根据合同id找到对应的合同信息
            expenseRecord.Balance = contract.Deposit - productApply.Number * price;//消费记录表的余额
            contract.Deposit = contract.Deposit - productApply.Number * price;//计算合同表的余额
            product.Number = product.Number - productApply.Number;//计算商品剩余数量

            var trans = _db.Database.BeginTransaction();
            try
            {
                _db.Entry(expenseRecord).State = EntityState.Added;//向消费记录表插入数据
                //_db.Entry(inbound).State = EntityState.Modified;//2.修改合同表押金金额    
                _db.Entry(contract).State = EntityState.Modified;//更新合同表余额
                _db.Entry(productApply).State = EntityState.Modified;
                //3.更新商品表数量（考虑是否触发阈值）             
                _db.Entry(product).State = EntityState.Modified;//更新商品表商品数量
                if (product.Number <= product.Threshold)
                {
                    MessageInfo messageInfo = new MessageInfo()
                    {
                        Contents = $"请去进{product.ProductName}",
                        StaffRecId = 1,
                        StaffSendId = 0,
                        CreateTime = DateTime.Now,
                        IsDelete = 0,
                        Href = "/Product/ProductList",
                        IsRead = 0,
                        Times = DateTime.Now
                    };
                    _db.Entry(messageInfo).State = EntityState.Added;
                }
                trans.Commit();
                _db.SaveChanges();
                ResMessage resMessage = ResMessage.Success("");
                resMessage.msg = msg;
                resMessage.code = 0;
                return resMessage;
            }
            catch (Exception ex)
            {
                //日志 记录异常信息
                trans.Rollback();
                return ResMessage.Fail(ex.Message);
            }
        }



        //生成条形码
        private string GenerateBarcode(ProductVM productVM)
        {
            // 1. 生成唯一编号
            string barcodeNumber = $"{DateTime.Now:yyyyMMddHHmmss}{new Random().Next(1000, 9999)}";

            // 2. 创建条形码图片
            var barcodeWriter = new BarcodeWriter
            {
                Format = BarcodeFormat.CODE_128,
                Options = new EncodingOptions { Height = 100, Width = 300, Margin = 10 }
            };
            var barcodeImage = barcodeWriter.Write(barcodeNumber);

            // 3. 确保目标文件夹存在
            string imgPath = ConfigurationManager.AppSettings["ImgPath"];
            if (!Directory.Exists(imgPath))
            {
                Directory.CreateDirectory(imgPath);
            }

            // 4. 保存图片
            string fileName = $"{barcodeNumber}.png";
            string physicalPath = imgPath + fileName;
            try
            {
                barcodeImage.Save(physicalPath);
                return $"/assets/img/{fileName}"; // 返回相对路径
            }
            catch (Exception ex)
            {
                throw new Exception($"保存条形码图片失败: {ex.Message}");
            }
        }




    }
}
